package com.gilight.base.service.print;

import com.gilight.base.admin.brand.AdminBrandService;
import com.gilight.base.component.CacheComponent;
import com.gilight.base.component.CacheConst;
import com.gilight.base.dao.SysZzjgMapper;
import com.gilight.base.dao.UnimallNousermapDao;
import com.gilight.base.dto.feier.FeiErClientDto;
import com.gilight.base.mapper.UserMapper;
import com.gilight.base.model.BrandDo;
import com.gilight.base.model.SysZzjg;
import com.gilight.base.model.UnimallNousermap;
import com.gilight.base.model.order.OrderSkuDO;
import com.gilight.base.model.uni.UserDO;
import com.gilight.base.service.impl.UserServiceImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service("feier")
public class FeiErPrintImpl implements IPrint{

    public static final String URL = "http://api.feieyun.cn/Api/Open/";//不需要修改

    /**
     * 406979945@qq.com
     */
    public static final String USER = "406979945@qq.com";//*必填*：账号名
    public static final String UKEY = "R9MpPEDZf7gIC72p";//*必填*: 飞鹅云后台注册账号后生成的UKEY 【备注：这不是填打印机的KEY】
    public static final String SN = "*********";//*必填*：打印机编号，必须要在管理后台里添加打印机或调用API接口添加之后，才能调用API
    @Autowired
    private SysZzjgMapper sysZzjgMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AdminBrandService adminBrandService;
    @Autowired
    private CacheComponent cacheComponent;
    @Autowired
    private UnimallNousermapDao unimallNousermapDao;
    @Autowired
    private UserServiceImpl userServiceImp;
    private static final Logger logger = LoggerFactory.getLogger(FeiErPrintImpl.class);
    //TODO

    private String formatStr = "yyyy-MM-dd HH:mm:ss";

    @Override
    public String printXiaoPiao(Long zzjgId, List<OrderSkuDO> orderDOList, Integer totalPrice, Long userId, String phone, String mono) {

        SysZzjg zzjg = getSysZzjg(zzjgId);
        if(zzjg == null){
            logger.info("初始化小票机失败");
            return "";
        }
        if(StringUtils.isEmpty(mono)){
            mono = "无";
        }
        String sn = zzjg.getXiaoPiaoSn();
        UserDO userDO = userMapper.selectById(userId);
        String nickName = userDO.getNickname();
        if(StringUtils.isEmpty(nickName)){
            nickName = "微信用户";
        }
        String zzjgPhone = zzjg.getPhone();
        //方法1
            //标签说明：
            //单标签:
            //"<BR>"为换行,"<CUT>"为切刀指令(主动切纸,仅限切刀打印机使用才有效果)
            //"<LOGO>"为打印LOGO指令(前提是预先在机器内置LOGO图片),"<PLUGIN>"为钱箱或者外置音响指令
            //成对标签：
            //"<CB></CB>"为居中放大一倍,"<B></B>"为放大一倍,"<C></C>"为居中,<L></L>字体变高一倍
            //<W></W>字体变宽一倍,"<QR></QR>"为二维码,"<BOLD></BOLD>"为字体加粗,"<RIGHT></RIGHT>"为右对齐
            //拼凑订单内容时可参考如下格式
            //根据打印纸张的宽度，自行调整内容的格式，可参考下面的样例格式
        String specOrderNo = "";
        String dataStr = "";
        if(orderDOList!=null&&orderDOList.size()>0){
            OrderSkuDO orderSkuDO = orderDOList.get(0);
            specOrderNo = orderSkuDO.getSpecOrder();
            dataStr = DateFormatUtils.format(orderSkuDO.getGmtCreate(),this.formatStr);
        }
        String content;

            content =  ""+zzjg.getZzjgName()+"<BR>";
            content += "电话："+zzjgPhone+"<BR>";
            content += "单号："+specOrderNo+"<BR>";
            content += "时间："+dataStr+"<BR>";
            content += "--------------------------------<BR>";
            content +=  "<B>顾客备注:"+mono+"</B><BR>";
            content += "--------------------------------<BR>";
            content += "名称　　　　　 单价  数量 金额<BR>";
            content += "--------------------------------<BR>";
            for(OrderSkuDO orderSkuDO:orderDOList){
                String spuTitle = orderSkuDO.getSpuTitle();
                String specification = orderSkuDO.getSpecification();
                specification = FormatButtonText(specification,16);
                Integer skuNum = orderSkuDO.getNum();
                Double price = orderSkuDO.getPrice()*1.0;
                String strPrice = FormatButtonText(String.valueOf(price/100),7);
                String strSkuNum = FormatButtonText(String.valueOf(skuNum),5);
                String  finalPrice = String.valueOf((skuNum*price)/100);
                content += spuTitle+"<BR>";
                content +=specification+strPrice+strSkuNum+finalPrice+"<BR>";
                content += "--------------------------------<BR>";
            }
//
//            content += "饭　　　　　　 1.0    1   1.0<BR>";
//            content += "炒饭　　　　　 10.0   10  10.0<BR>";
//            content += "蛋炒饭　　　　 10.0   10  100.0<BR>";
//            content += "鸡蛋炒饭　　　 100.0  1   100.0<BR>";
//            content += "番茄蛋炒饭　　 1000.0 1   100.0<BR>";
//            content += "西红柿蛋炒饭　 1000.0 1   100.0<BR>";
//            content += "西红柿鸡蛋炒饭 100.0  10  100.0<BR>";
            content += "用户："+nickName+"<BR>";
            content += "电话："+phone+"<BR>";
            content += "备注："+mono+"<BR>";
            content += "--------------------------------<BR>";
            content += "合计："+String.valueOf((totalPrice*1.0)/100)+"<BR>";
            content += "支付方式：微信支付<BR>";
//            content += "店铺电话："+zzjgPhone+"<BR>";
            content += "<QR>http://www.tangbantian.com/</QR>";

            //通过POST请求，发送打印信息到服务器
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(30000)//读取超时
                    .setConnectTimeout(30000)//连接超时
                    .build();

            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(requestConfig)
                    .build();

            HttpPost post = new HttpPost(URL);
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("user",USER));
            String STIME = String.valueOf(System.currentTimeMillis()/1000);
            nvps.add(new BasicNameValuePair("stime",STIME));
            nvps.add(new BasicNameValuePair("sig",signature(USER,UKEY,STIME)));
            nvps.add(new BasicNameValuePair("apiname","Open_printMsg"));//固定值,不需要修改
            nvps.add(new BasicNameValuePair("sn",sn));
            nvps.add(new BasicNameValuePair("content",content));
            nvps.add(new BasicNameValuePair("times","1"));//打印联数

            CloseableHttpResponse response = null;
            String result = null;
            try
            {
                post.setEntity(new UrlEncodedFormEntity(nvps,"utf-8"));
                response = httpClient.execute(post);
                int statecode = response.getStatusLine().getStatusCode();
                if(statecode == 200){
                    HttpEntity httpentity = response.getEntity();
                    if (httpentity != null){
                        //服务器返回的JSON字符串，建议要当做日志记录起来
                        result = EntityUtils.toString(httpentity);
                    }
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            finally{
                try {
                    if(response!=null){
                        response.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    post.abort();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return result;

    }

    private SysZzjg getSysZzjg(Long zzjgId) {
        SysZzjg zzjg = null;
        if(cacheComponent.hasKey(CacheConst.ZZJG_CACHE_BY_ID+ zzjgId)){
            zzjg = cacheComponent.getObj(CacheConst.ZZJG_CACHE_BY_ID+ zzjgId,SysZzjg.class);
        }else{
            zzjg = sysZzjgMapper.selectByPrimaryKey(zzjgId);
            cacheComponent.putObj(CacheConst.ZZJG_CACHE_BY_ID+ zzjgId,zzjg,3600);
        }
        return zzjg;
    }

    @Override
    public String printLabelMsg(Long zzjgId, List<OrderSkuDO> orderDOList, Integer totalPrice, Long userId, String phone, String mono) {
        SysZzjg zzjg = null;
        if(cacheComponent.hasKey(CacheConst.ZZJG_CACHE_BY_ID+zzjgId)){
            zzjg = cacheComponent.getObj(CacheConst.ZZJG_CACHE_BY_ID+zzjgId,SysZzjg.class);
        }else{
            zzjg = sysZzjgMapper.selectByPrimaryKey(zzjgId);
            cacheComponent.putObj(CacheConst.ZZJG_CACHE_BY_ID+zzjgId,zzjg,3600);
        }
        if(zzjg == null){
            logger.info("初始化小票机失败");
            return "";
        }
//        UserDO userDO = userMapper.selectById(userId);
        String sn = zzjg.getBiaoQianSn();
        String zzjgPhone = zzjg.getPhone();
        String desInfo = "新式鲜奶茶、现打气泡水";
        try {
            BrandDo brandDo = adminBrandService.getById(zzjg.getBrandId());
            if(StringUtils.isNotEmpty(brandDo.getDescription())) {
                desInfo = brandDo.getDescription();
            }else{
                logger.info("没有商家描述么？"+brandDo.getDescription());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        logger.info("什么情况？"+orderDOList.size());
        logger.info("sn是多少"+sn);
        if(StringUtils.isEmpty(mono)){
            mono = "无";
        }
        Integer size = orderDOList.size();
        for(int i = 0;i<size;i++) {
            logger.info("不会没有进吧？？" + orderDOList.size());
            OrderSkuDO orderSkuDO = orderDOList.get(i);
            String specOrderNo = orderSkuDO.getSpecOrder();
            String dataStr = DateFormatUtils.format(orderSkuDO.getGmtCreate(), this.formatStr);
            Integer coldNum = orderSkuDO.getNum();
            if (coldNum == null) {
                coldNum = 1;
            }
            for (int j = 0; j < coldNum; j++) {
                String content;
                content = "<DIRECTION>1</DIRECTION>";//设定打印时出纸和打印字体的方向，n 0 或 1，每次设备重启后都会初始化为 0 值设置，1：正向出纸，0：反向出纸，
//            content += "<TEXT x='9' y='10' font='12' w='1' h='2' r='0'>#001                       "+(i+1)+"/"+size+"</TEXT>" +
//                    "<TEXT x='9' y='30>"+orderSkuDO.getSpuTitle()+"</TEXT>"+
//                    "<TEXT x='80' y='80' font='12' w='2' h='2' r='0'>"+orderSkuDO.getSpecification() +"</TEXT>" +
//                    "<TEXT x='9' y='180' font='12' w='1' h='1' r='0'>"+nickName+"       "+phone+"</TEXT>";//40mm宽度标签纸打印例子，打开注释调用标签打印接口打印
                content += "<TEXT x='5' y='2' font='10' >#" + (i + 1) + "/" + size + "|"+(coldNum>1?(j+1):"")+"</TEXT>\n" +
                        "<TEXT x='5' y='35'>单号:" + specOrderNo + "</TEXT>\n" +
                        "<TEXT x='5' y='70' font='16' w='2'>" + orderSkuDO.getSpuTitle() + "</TEXT>\n" +
                        "<TEXT x='5' y='100' >" + orderSkuDO.getSpecification() + "</TEXT>\n" +
                        "<TEXT x='5' y='130' >" + dataStr + "</TEXT>\n" +
                        "<TEXT x='5' y='160' >"+desInfo+"</TEXT>\n" +
                        "<TEXT x='5' y='200'>外购热线:"+zzjgPhone+"</TEXT>";

                logger.info(content);
                //通过POST请求，发送打印信息到服务器
                RequestConfig requestConfig = RequestConfig.custom()
                        .setSocketTimeout(30000)//读取超时
                        .setConnectTimeout(30000)//连接超时
                        .build();

                CloseableHttpClient httpClient = HttpClients.custom()
                        .setDefaultRequestConfig(requestConfig)
                        .build();

                HttpPost post = new HttpPost(URL);
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                nvps.add(new BasicNameValuePair("user", USER));
                String STIME = String.valueOf(System.currentTimeMillis() / 1000);
                nvps.add(new BasicNameValuePair("stime", STIME));
                nvps.add(new BasicNameValuePair("sig", signature(USER, UKEY, STIME)));
                nvps.add(new BasicNameValuePair("apiname", "Open_printLabelMsg"));//固定值,不需要修改
                nvps.add(new BasicNameValuePair("sn", sn));
                nvps.add(new BasicNameValuePair("content", content));
                nvps.add(new BasicNameValuePair("times", "1"));//打印联数

                CloseableHttpResponse response = null;
                String result = null;
                try {
                    post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
                    response = httpClient.execute(post);
                    int statecode = response.getStatusLine().getStatusCode();
                    if (statecode == 200) {
                        HttpEntity httpentity = response.getEntity();
                        if (httpentity != null) {
                            //服务器返回的JSON字符串，建议要当做日志记录起来
                            result = EntityUtils.toString(httpentity);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (response != null) {
                            response.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        post.abort();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return "成功";

    }


    //方法3
    private static String queryOrderState(String orderid){

        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user",USER));
        String STIME = String.valueOf(System.currentTimeMillis()/1000);
        nvps.add(new BasicNameValuePair("stime",STIME));
        nvps.add(new BasicNameValuePair("sig",signature(USER,UKEY,STIME)));
        nvps.add(new BasicNameValuePair("apiname","Open_queryOrderState"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("orderid",orderid));

        CloseableHttpResponse response = null;
        String result = null;
        try
        {
            post.setEntity(new UrlEncodedFormEntity(nvps,"utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if(statecode == 200){
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null){
                    //服务器返回
                    result = EntityUtils.toString(httpentity);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally{
            try {
                if(response!=null){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 添加打印机
     * @param feiErClientDtos
     * @return
     */
    @Override
    public String addPrint(List<FeiErClientDto> feiErClientDtos) {
        String snlist = feiErClientDtos.stream().map(feiErClientDto -> {
             return feiErClientDto.toString();
        }).collect(Collectors.joining("\\n"));

        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user",USER));
        String STIME = String.valueOf(System.currentTimeMillis()/1000);
        nvps.add(new BasicNameValuePair("stime",STIME));
        nvps.add(new BasicNameValuePair("sig",signature(USER,UKEY,STIME)));
        nvps.add(new BasicNameValuePair("apiname","Open_printerAddlist"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("printerContent",snlist));

        CloseableHttpResponse response = null;
        String result = null;
        try
        {
            post.setEntity(new UrlEncodedFormEntity(nvps,"utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if(statecode == 200){
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null){
                    result = EntityUtils.toString(httpentity);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally{
            try {
                if(response!=null){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 打印优惠卷
     * 实际上就是发放优惠卷
     * 当老带新，并且新用户完成一次消息时会发放优惠卷给老用户
     *
     * @param userId
     * @param zzjgId
     */
    @Override
    public void printCoupon(Long userId, Long zzjgId) {
        UnimallNousermap unimallNousermap = unimallNousermapDao.selectByUserId(userId);
        if(unimallNousermap != null){  //说明该用户是被老用户分享进来的
            UserDO userDO = new UserDO();
            Long oldUserId = unimallNousermap.getOldUserid();
            if(oldUserId == null) return;
            userDO.setId(oldUserId);
            try {
                SysZzjg sysZzjg = this.getSysZzjg(zzjgId);
                BrandDo brandDo = adminBrandService.getById(sysZzjg.getBrandId());
                /**
                 * 类型2老用户领取邀请卷
                 * 新用户在哪家店消费，就会发哪家店单独发的老带新卷，同样也会同时拿总部的平台卷
                 */
                userServiceImp.obtionCoupon(userDO, brandDo.getId(),2,zzjgId);
                unimallNousermap.setStatus(0);//更新绑定状态为已经领取
                unimallNousermapDao.updateByPrimaryKeySelective(unimallNousermap);
            } catch (Exception e) {
               logger.error("老用户获取优惠卷异常",e);
            }
        }
    }

    //生成签名字符串
    private static String signature(String USER,String UKEY,String STIME){
        String s = DigestUtils.sha1Hex(USER+UKEY+STIME);
        return s;
    }
    public   static  String FormatButtonText(String targetStr,Integer strLength) {
        int curLength = 0;
        try {
            curLength = targetStr.getBytes("gbk").length;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if(targetStr!=null && curLength>strLength)
            targetStr = SubStringByte(targetStr,strLength);
        String newString = "";
        int cutLength = strLength-curLength;
        for(int i=0;i<cutLength;i++)
            newString +=" ";
        return targetStr+newString;
    }
    public   static  String SubStringByte(String targetStr,Integer strLength) {

        while(targetStr.getBytes().length>strLength)
            targetStr = targetStr.substring(0,targetStr.length()-1);
        return targetStr;
    }
//    public static Long getCyOrderId(Long oId){
//        try {
//            if (oId == 0) {
//                return oId;
//            }
//            oId = oId % 100L;
//            if (oId == 0) {
//                oId = 100L;
//            }
//            return oId;
//        }catch (Exception e){ //如果出现异常将返回完整的单号
//            e.printStackTrace();
//            return oId;
//        }
//    }
    public static void main(String [] args){

//          Long aa = FeiErPrintImpl.getCyOrderId(1100L);
//        System.out.println(aa);
//        String a = FormatButtonText("a，11",16);
//        System.out.println(a);
//        FeiErClientDto feiErClientDto = new FeiErClientDto("456","yuyu","你好","10086");
//        FeiErClientDto feiErClientDto1 = new FeiErClientDto("890","mimi","你好","10010");
//        List<FeiErClientDto> feiErClientDtos = new ArrayList<>();
//        feiErClientDtos.add(feiErClientDto);
//        feiErClientDtos.add(feiErClientDto1);
//        new FeiErPrintImpl().addPrint(feiErClientDtos);
    }
}
